/*********************************************************************************
 *     Copyright:  (C) 2022 Nikel
 *                 All rights reserved.
 *
 *    Filename:  bc28.c
 *    Description:  This file is for bc28 module to communication
 *
 *    Version:  1.0.0
 *    Author:  zhouyanlin <www.zhouyanlin1222@qq.com>
 *    ChangeLog:  1, Release initial version on "06/05/22 08:53:34"
 *
 ********************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gpio.h"
#include "bc28.h"

/*
 *
 * NB_IoT Module debug macro,
 * comment the following two macro definitions to cancel debug printing
 *
 */
//#define CONFIG_NB_IoT_DEBUG
//#define CONFIG_NB_IoT_PRINT

#ifdef CONFIG_NB_IoT_DEBUG
#define nb_dbg(format,args...) printf(format, ##args)
#else
#define nb_dbg(format,args...) do{} while(0)
#endif

#ifdef CONFIG_NB_IoT_PRINT
#define nb_printf(format,args...) printf(format, ##args)
#else
#define nb_printf(format,args...) do{} while(0)
#endif
#define	ON				1
#define	OFF				0

/* The prefix string for reporting data */
#define SEND_TEM_STR		"AT+QLWULDATAEX=9,02000A0004"	/* temperature prefix */
#define SEND_HUM_STR		"AT+QLWULDATAEX=9,0200090004"	/* humidity prefix */
#define SEND_SIGN_STR		"AT+QLWULDATAEX=9,0200200004"	/* signal strength prefix */
#define SEND_LUX_STR		"AT+QLWULDATAEX=9,0200150004"	/* slight strength prefix */
#define SEND_SOIL_HUM_STR	"AT+QLWULDATAEX=9,0200160004"	/* soil humidity prefix */

/* Relay switch status */
uint8_t	relay_hum_status = 0;
uint8_t	relay_tem_status = 0;


int nb_iot_reset(void)
{
	nb_printf("NB-IoT start to reset ...\r\n");
	if(  send_atcmd_check_ok("AT+NRB\r\n", 6000) )
	{
		nb_printf("NB-IoT reset failure\r\n");
		return -1;
	}
	nb_printf("NB-IoT reset successfully\r\n");
	return 0;

}

int nb_iot_module_init(char *frequency_band_at)
{
	int       i;

	/* check function input arguments validation */
	if(  !frequency_band_at || strlen(frequency_band_at)<=0 )
	{
		printf("ERROR: Invalid input arguments\r\n");
		return -1;
	}

	nb_printf("INFO: Init NB-IoT module now...\r\n");

	/* It takes about 5 seconds for the NB module to receive AT commands normally after being powered on.
	 * Here, the loop waits for 6 seconds */
	for(i=0; i<6; i++)
	{
		if( !send_atcmd_check_module() )	/* Send the AT command to check whether the module is powered on normally */
		{
			nb_printf("INFO: Send AT to NB-IoT and got reply ok\r\n");
			break;
		}

		HAL_Delay(100);
	}

	if( i>= 6 )
	{
		nb_printf("ERROR: Can't receive AT replay after reset\r\n");
		return -2;
	}

	/* Restart the NB-iot module */
	 if( nb_iot_reset() )
	 {
		 nb_printf("ERROR: Can't receive AT replay after reset\r\n");
		 return-3;
	 }

	/* Disable the RF to prepare for changing the frequency band */
	if( send_atcmd_check_ok("AT+CFUN=0\r\n", 500) )
	{
		nb_printf("ERROR: Can't receive AT replay after reset\r\n");
		return -4;
	}

	/*  Change the frequency band to telecom frequency band 5,8 */
	if( send_atcmd_check_ok(frequency_band_at, 500) )
	{
		nb_printf("ERROR: Can't receive AT replay after reset\r\n");
		return -5;

	}

	/* Open the radio frequency */
	if( send_atcmd_check_ok("AT+CFUN=1\r\n", 3000) )
	{
		nb_printf("ERROR: Can't receive AT replay after reset\r\n");
		return -6;
	}

	/* Check whether the SIM card is read successfully */
	if( send_atcmd_check_ok("AT+CIMI\r\n", 500) )
	{
		nb_printf("ERROR: Can't receive AT replay after reset\r\n");
		return -7;
	}

	return 0;
}


int nb_iot_connect(char *paltform_at)
{
	/* check function input arguments validation */
	if(  NULL == paltform_at || strlen(paltform_at)<=0 )
	{
		printf("ERROR: Invalid input arguments\r\n");
		return -1;
	}

	/* Set the IP address and port of the cloud platform */
	if( send_atcmd_check_ok(paltform_at, 500) )
	{
		nb_printf("ERROR: Send CMD:%s get reply failure!\r\n", paltform_at);
		return -2;
	}

	/* Query the network attachment status.
	 * If the module is not enabled, the module starts to attach to the network*/
	if( send_atcmd("AT+CGATT?\r\n", "CGATT:1", 500, NULL, 0) )
	{
		nb_printf("INFO: Net is not sticking and reconnect now\r\n");

		if( send_atcmd("AT+CGATT=1\r\n", "3", 5000, NULL, 0) )
		{
			nb_printf("ERROR: Send sticking net CMD:AT+CGATT=1 get reply failure!\r\n");
			return -3;
		}

	}

	/* Query the platform registration status.
	 * If the platform is not registered, the module starts to register */
	if( send_atcmd("AT+NMSTATUS?\r\n", "ENABLED", 500, NULL, 0) )
	{
		nb_printf("INFO: Platform is not register and register now!\r\n");

		if( send_atcmd_check_ok("AT+QLWSREGIND=0\r\n", 500) )
		{
			nb_printf("ERROR: Send register CMD: AT+QLWSREGIND=0 get reply failure!\r\n");
			return -4;
		}

	}

	return 0;
}

int nb_iot_get_sign(void)
{
	char *result = NULL;
	char sign_char[2];
	int	 sign_num = -1;
	if( send_atcmd("AT+CSQ\r\n", 0, 500, NULL, 0) )
	{
		nb_printf("ERROR: Send get signal CMD: AT+QLWSREGIND=0 get reply failure!\r\n");
		return -1;
	}

	if( ( result = (strstr(g_atcmd_rxbuf, ":"))) !=NULL )
	{
		sign_char[0] = *(++result);
		sign_char[1] = *(++result);
		sign_num = atoi(sign_char);

		nb_printf("signal strength : %d\r\n", sign_num);
		return sign_num;
	}

}

int nb_iot_send_TH(float temperature, float humidity)
{

	/*  change data to integer from float*/
	int temp = temperature;
	int hum = humidity;
	char tem_buf[64];	/* Stores a formatted string of data to be sent */
	char hum_buf[64];

	memset(tem_buf, 0, sizeof(tem_buf) );
	memset(hum_buf, 0, sizeof(hum_buf) );

	snprintf(tem_buf, sizeof(tem_buf),"%s%08x,0x0100\r\n",SEND_TEM_STR,temp);
	snprintf(hum_buf, sizeof(hum_buf),"%s%08x,0x0100\r\n",SEND_HUM_STR,hum);

	if( send_atcmd(tem_buf, "QLWULDATASTATUS:4", 1000, NULL, 0) != 0 )
	{
		return -2;
	}

	HAL_Delay(500);

	if( send_atcmd(hum_buf, "QLWULDATASTATUS:4", 1000, NULL, 0) != 0 )
	{
		return -3;
	}

	nb_printf("temperature:%d	humidity:%d\r\n", temp,hum);

	return 0;
}

int nb_iot_send_sign(int sign)
{
	char sign_buf[64];	/* Stores a formatted string of data to be sent */
	memset(sign_buf, 0, sizeof(sign_buf) );

	snprintf(sign_buf, sizeof(sign_buf),"%s%08x,0x0100\r\n",SEND_SIGN_STR,sign);

	if( send_atcmd(sign_buf, "QLWULDATASTATUS:4", 1000, NULL, 0) != 0 )
	{
		return -1;
	}

	return 0;

}

int nb_iot_send_lux(int Lux)
{
	char lux_buf[64];	/* Stores a formatted string of data to be sent */
	memset(lux_buf, 0, sizeof(lux_buf) );

	snprintf(lux_buf, sizeof(lux_buf),"%s%08x,0x0100\r\n",SEND_LUX_STR,Lux);
	if( send_atcmd(lux_buf, "QLWULDATASTATUS:4", 1000, NULL, 0)  )
	{
		return -1;
	}

	return 0;
}

int nb_iot_send_soil_humidity(int humidity)
{
	char humidity_buf[64];	/* Stores a formatted string of data to be sent */
	memset(humidity_buf, 0, sizeof(humidity_buf) );

	snprintf(humidity_buf, sizeof(humidity_buf),"%s%08x,0x0100\r\n",SEND_SOIL_HUM_STR, humidity);
	if( send_atcmd(humidity_buf, "QLWULDATASTATUS:4", 1000, NULL, 0)  )
	{
		return -1;
	}

	return 0;
}

int parse_recv_cmd(char * cmd)
{
	/* check function input arguments validation */
	if( NULL == cmd )
	{
		printf("ERROR: Invalid input arguments\r\n");
		return -1;
	}

	if (g_atcmd_bytes > 0)
		{
				HAL_Delay(200);  /* Wait AT command reply receive over */
//				HAL_UART_Transmit(&huart1 , (uint8_t *)g_uart3_rxbuf, g_uart3_bytes, 0xFF);

				if(strstr(cmd, "8,061F45") != NULL)	/* Control temperature relay instructions */
				{
					HAL_Delay(1);

					if( (strstr(cmd, "0101") != NULL) && (OFF == relay_tem_status) )	/* Open relay */
					{
						turn_relay(Relay2, ON);
						turn_led(RedLed, ON);
						printf("Turn temperature relay ON!!!\r\n");
						printf("-----------------\r\n");
						relay_tem_status = ON;
					}

					/* Shut down relay */
					else if(ON == relay_tem_status)
					{
						turn_relay(Relay2, OFF);
						turn_led(RedLed, OFF);
						printf("Turn temperature relay OFF!!!\r\n");
						printf("-----------------\r\n");
						relay_tem_status = OFF;
					}

				}

				else if( (strstr(cmd, "8,061F47") != NULL) )	/* Control humidity relay instructions */
				{
					HAL_Delay(1);

					if( (strstr(cmd, "0101") != NULL) && (OFF == relay_hum_status) )	/* Open relay */
					{
						turn_relay(Relay1, ON);
						turn_led(BlueLed, ON);
						printf("Turn humidity relay ON!!!\r\n");
						printf("-----------------\r\n");
						relay_hum_status = ON;
					}

					else if(ON == relay_hum_status)
					{
						turn_relay(Relay1, OFF);
						turn_led(BlueLed, OFF);
						printf("Turn humidity relay OFF!!!\r\n");
						printf("-----------------\r\n");
						relay_hum_status = OFF;
					}

				}

//				clear_atcmd_rxbuf();
				return 0;
		}

}
